home *** CD-ROM | disk | FTP | other *** search
/ PCGUIA 127 / PC Guia 127.iso / Software / Utils / NEW - Stylish / Bin / stylish-0.2.1-fx+fl+tb.xpi / chrome / stylish.jar / content / stylishCommon.js < prev    next >
Text File  |  2006-01-06  |  8KB  |  192 lines

  1. /*
  2.     This code is licensed under the GPL (http://www.gnu.org/copyleft/gpl.txt) 
  3.     Author: Jason Barnabe <jason_barnabe@fastmail.fm>
  4.     Release date: Dec 20, 2005
  5.     Contributors:
  6.         Reading from chrome file courtesy Torisugari <http://forums.mozillazine.org/viewtopic.php?p=921150#921150>
  7. */
  8.  
  9. function StylishCommon() {
  10.  
  11.     this.XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
  12.     this.HTMLNS = "http://www.w3.org/1999/xhtml";
  13.     this.codePrefix = "data:text/css,";
  14.  
  15.     this.containerURI = "urn:stylish:userstyles";
  16.     this.descriptionURI = "urn:stylish#description";
  17.     this.enabledURI = "urn:stylish#enabled";
  18.     this.codeURI = "urn:stylish#code";
  19.     this.siteURLURI = "urn:stylish#url";
  20.     this.siteURLPrefixURI = "urn:stylish#urlPrefix";
  21.     this.siteDomainURI = "urn:stylish#domain";
  22.  
  23.     this.ios = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
  24.     this.sss = Components.classes["@mozilla.org/content/style-sheet-service;1"].getService(Components.interfaces.nsIStyleSheetService);
  25.  
  26.     //Returns "file://(profile folder)/stylish.rdf"
  27.     this.getDatasourceURI = function() {
  28.         var file = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile);
  29.         file.append("stylish.rdf");
  30.         var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
  31.         if (!file.exists()) {
  32.             //either this is the first run or the user deleted his file (the bastard)
  33.  
  34.             //read the default file's contents (courtesy Torisugari <http://forums.mozillazine.org/viewtopic.php?p=921150#921150>)
  35.             var scriptableStream = Components.classes["@mozilla.org/scriptableinputstream;1"].getService(Components.interfaces.nsIScriptableInputStream);
  36.             var channel = ioService.newChannel("chrome://stylish/content/stylish-default.rdf", null, null);
  37.             var input = channel.open();
  38.             scriptableStream.init(input);
  39.             var data = scriptableStream.read(input.available());
  40.             scriptableStream.close();
  41.             input.close();
  42.  
  43.             //write the contents to the profile file
  44.             var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
  45.             foStream.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
  46.             foStream.write(data, data.length);
  47.             foStream.close();
  48.         }
  49.         return ioService.newFileURI(file).spec;
  50.     }
  51.  
  52.     this.datasourceURI = this.getDatasourceURI();
  53.     this.ds = new RDFDataSource(this.datasourceURI);
  54.  
  55.     //Toggles the disabled attribute of a node
  56.     //node - the node to toggle
  57.     //saveImmediately - save the changes (set to false and do it yourself for multiple updates)
  58.     this.toggleNodeDisable = function(node, saveImmediately) {
  59.         var previousTarget = node.getTarget(stylishCommon.enabledURI).getValue();
  60.         var newTarget;
  61.         if (previousTarget == "true") {
  62.             newTarget = "false";
  63.             stylishCommon.unregisterNode(node);
  64.         } else {
  65.             newTarget = "true";
  66.             stylishCommon.registerNode(node);
  67.         }
  68.         node.modifyTarget(stylishCommon.enabledURI, previousTarget, newTarget);        
  69.         if (saveImmediately) {
  70.             this.ds.save();
  71.             this.ds.refresh(true);
  72.         }
  73.     }
  74.  
  75.     //Register code by stylish.rdf node uri
  76.     this.registerURI = function(uri) {
  77.         var node = this.ds.getNode(uri);
  78.         stylishCommon.registerNode(node);
  79.     }
  80.  
  81.     //Register code by stylish.rdf node
  82.     this.registerNode = function(node) {
  83.         var uri = stylishCommon.getNodeURI(node);
  84.         var css = node.getTarget("urn:stylish#code").getValue();
  85.         var cssURL = stylishCommon.codePrefix + css;
  86.         var u = stylishCommon.ios.newURI(cssURL, null, null);
  87.         stylishCommon.sss.loadAndRegisterSheet(u, stylishCommon.sss.USER_SHEET);
  88.  
  89.         //instant apply
  90.         var docs = this.getDocuments();
  91.         for (var i = 0; i < docs.length; i++) {
  92.             var childDoc = docs[i];
  93.             var stylesheetLink = childDoc.createElementNS(stylishCommon.HTMLNS, "link");
  94.             stylesheetLink.id = stylishCommon.getDOMId(uri);
  95.             stylesheetLink.type = "text/css";
  96.             stylesheetLink.rel = "stylesheet";
  97.             stylesheetLink.href = cssURL;
  98.             stylesheetLink.charset = "UTF-8"; 
  99.  
  100.             //we can't use xml processing instructions because then they'd get put into the DOM and some code in the codebase assumes that no processing instructions are in the DOM <https://bugzilla.mozilla.org/show_bug.cgi?id=319654>. so let's use html:link and try to put it in an appropriate place
  101.             var nodeToAppendTo = null;
  102.             //XHTML head
  103.             var heads = childDoc.getElementsByTagNameNS(stylishCommon.HTMLNS, "head");
  104.             if (heads.length >= 1) {
  105.                 nodeToAppendTo = heads[0];
  106.             }
  107.             if (!nodeToAppendTo) {
  108.                 //HTML head
  109.                 var heads = childDoc.getElementsByTagNameNS(null, "head");
  110.                 if (heads.length >= 1) {
  111.                     nodeToAppendTo = heads[0];
  112.                 }
  113.             }
  114.             if (!nodeToAppendTo) {
  115.                 //just jam it in the document element and hope for the best
  116.                 nodeToAppendTo = childDoc.documentElement;
  117.             }
  118.             nodeToAppendTo.appendChild(stylesheetLink);
  119.         }
  120.  
  121.     }
  122.  
  123.     //Unregister code by stylish.rdf node uri
  124.     this.unregisterURI = function(uri) {
  125.         var node = this.ds.getNode(uri);
  126.         stylishCommon.unregisterNode(node);
  127.     }
  128.  
  129.     //Unregister code by stylish.rdf node
  130.     this.unregisterNode = function(node) {
  131.         var uri = stylishCommon.getNodeURI(node);
  132.         var css = node.getTarget("urn:stylish#code").getValue();
  133.         var cssURL = stylishCommon.codePrefix + css;
  134.         var u = stylishCommon.ios.newURI(cssURL, null, null);
  135.         if (stylishCommon.sss.sheetRegistered(u, stylishCommon.sss.USER_SHEET)) {
  136.             stylishCommon.sss.unregisterSheet(u, stylishCommon.sss.USER_SHEET);
  137.         } else {
  138.             //this can happen if someone's been fooling around with the rdf file since startup. Once Firefox is restarted, they'll be in sync again
  139.             dump("Stylish: Sheet not registered, so I can't unregister it.\n");
  140.         }
  141.  
  142.         //instant unapply
  143.         //when we put the link code it, it strips whitespace, so to find a match we need to compare it to a the URL with no whitespace
  144.         var cssURLAttribute = cssURL.replace(/\n/, "");
  145.         var docs = this.getDocuments();
  146.         for (var i = 0; i < docs.length; i++) {
  147.             var childDoc = docs[i];
  148.             var link = childDoc.getElementById(stylishCommon.getDOMId(uri));
  149.             if (link) {
  150.                 link.parentNode.removeChild(link);
  151.             }
  152.         }
  153.     }
  154.  
  155.     //get the uri of the passed node
  156.     this.getNodeURI = function(node) {
  157.         return node.source.Value;
  158.     }
  159.  
  160.     this.getDOMId = function(uri) {
  161.         return "stylish-" + uri.substring(6, uri.length)
  162.     }
  163.  
  164.   //Returns an array of all open documents, whether chrome or content
  165.     this.getDocuments = function() {
  166.         var docs = [];
  167.  
  168.         var ww = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator);
  169.         var windows = ww.getXULWindowEnumerator(null);
  170.  
  171.         //For every window
  172.         while (windows.hasMoreElements()) {
  173.             //Get the window's main docshell
  174.             var windowDocShell = windows.getNext().QueryInterface(Components.interfaces.nsIXULWindow).docShell;
  175.             var containedDocShells = windowDocShell.getDocShellEnumerator(Components.interfaces.nsIDocShellTreeItem.typeAll, Components.interfaces.nsIDocShell.ENUMERATE_FORWARDS);
  176.             //For every docshell in the window
  177.             while (containedDocShells.hasMoreElements()) {
  178.                 // Get the corresponding document for this docshell
  179.                 var viewer = containedDocShells.getNext().QueryInterface(Components.interfaces.nsIDocShell).contentViewer;
  180.                 // Adblock might block iframes/frames. Null check the content viewer.
  181.                 if (viewer) {
  182.                     docs[docs.length] = viewer.DOMDocument;
  183.                 }
  184.             }
  185.         }
  186.         return docs;
  187.     }
  188.  
  189. }
  190.  
  191. var stylishCommon = new StylishCommon();
  192.